/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.station.client;/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import com.station.client.proxies.PCoordinates;

import java.util.TreeSet;

/**
 * @author 1
 */
public class Wave {
    int width;
    int height;
    int[][] cMap;
    PCoordinates inCoord;
    PCoordinates outCoord;
    final static int STATIC_OBJECTS = -2;
    final static int CARS = -1;
    final static int EMPTY = 0;
    final static int ROAD = 2;
    final static int ROAD_BORDER = 4;

    public Wave(int width, int height) {
        cMap = new int[width][height];
        this.width = width;
        this.height = height;
    }

    public void setInCoord(PCoordinates inCoord) {
        this.inCoord = inCoord;
    }

    public void setOutCoord(PCoordinates outCoord) {
        this.outCoord = outCoord;
    }

    public void modifyMap(PCoordinates coordinates, int value) {
        cMap[coordinates.x][coordinates.y] = value;
    }

    public int getValue(PCoordinates coordinates) {
        return cMap[coordinates.x][coordinates.y];
    }

    public void modifyMap(int x, int y, int value) { //использовать только при инициализации
        cMap[x][y] = value;
    }

    public boolean isEmpty(PCoordinates p) {
        return cMap[p.x][p.y] >= 0 && cMap[p.x][p.y] != 4;
    }


    public static int getSimpleMinWay(PCoordinates start, PCoordinates target) {
        return (Math.abs(target.x - start.x) + Math.abs(target.y - start.y));
    }

    public boolean isAvaliableStep(int targetX, int targetY, int cellState,int queneNumer) {
        boolean e = (cellState == ROAD && cMap[targetX][targetY] == ROAD_BORDER);//запрет на пересечение сплошной
        boolean d = (cellState == ROAD_BORDER && cMap[targetX][targetY] == ROAD);
        //определение очереди. Если впереди машина относится к той же очереди, разрешить ожидание.
        boolean q = true;
        SimpleCar c = Base.getCarByCoodinates(new PCoordinates(targetX,targetY));
        if (c != null)
            q = c.getQueneNumber() == queneNumer || c.getQueneNumber() == 100;// && !c.isProcFinished();
        return !e && !d && q;
    }


    public Move FindWayAStar(PCoordinates start, PCoordinates target, PCoordinates prevStep, int cellState,int queneNumber) {
        if (prevStep == null)
            prevStep = new PCoordinates(-1, -1);
        int currentX = start.x;
        int currentY = start.y;
        int leftCell = Integer.MAX_VALUE; //расстояния от клеток до цели
        int bottomCell = Integer.MAX_VALUE;
        int rightCell = Integer.MAX_VALUE;
        int topCell = Integer.MAX_VALUE;
        TreeSet<Integer>  cells = new TreeSet<Integer>();

        boolean inQuene;
        //определение расстояний в каждой клетке до цели
        if (currentY - 1 >= 0 && currentY - 1 < width && cMap[currentX][currentY - 1] != STATIC_OBJECTS && (prevStep.x != currentX || prevStep.y != currentY - 1)) {
            if (isAvaliableStep(currentX, currentY - 1,cellState,queneNumber))
                leftCell = Math.abs(target.x - currentX) + Math.abs(target.y - (currentY - 1));
            cells.add(leftCell);
        }


        if (currentX + 1 >= 0 && currentX + 1 < height && cMap[currentX + 1][currentY] != STATIC_OBJECTS && (prevStep.x != currentX + 1 || prevStep.y != currentY)) {
            if (isAvaliableStep(currentX + 1, currentY,cellState,queneNumber))
                bottomCell = Math.abs(target.x - (currentX + 1)) + Math.abs(target.y - currentY);
            cells.add(bottomCell);
        }

        if (currentY + 1 > 0 && currentY + 1 < width && cMap[currentX][currentY + 1] != STATIC_OBJECTS && (prevStep.x != currentX || prevStep.y != currentY + 1)) {
            if (isAvaliableStep(currentX, currentY + 1,cellState,queneNumber))
                rightCell = Math.abs(target.x - currentX) + Math.abs(target.y - (currentY + 1));
            cells.add(rightCell);
        }

        if (currentX - 1 > 0 && currentX - 1 < height && cMap[currentX - 1][currentY] != STATIC_OBJECTS && (prevStep.x != currentX - 1 || prevStep.y != currentY)) {
            if (isAvaliableStep(currentX - 1, currentY,cellState,queneNumber))
                topCell = Math.abs(target.x - (currentX - 1)) + Math.abs(target.y - currentY);
            cells.add(topCell);
        }


//        for (int s : cells)
//            if (s <= temp)
//                temp = s;
        int temp = Integer.MAX_VALUE;
        if (!cells.isEmpty())
            temp = cells.first(); //нахождение минимального значения
        Move result = null;
        if (temp != Integer.MAX_VALUE) {   //todo   //конфликт двух клеток
            if (bottomCell == temp)
                result = new Move(new PCoordinates(currentX + 1, currentY), Direction.Down);
            if (leftCell == temp)
                result = new Move(new PCoordinates(currentX, currentY - 1), Direction.Left);
            if (rightCell == temp)
                result = new Move(new PCoordinates(currentX, currentY + 1), Direction.Right);
            if (topCell == temp)
                result = new Move(new PCoordinates(currentX - 1, currentY), Direction.Up);
        }
        if (result != null && cMap[result.coordinates.x][result.coordinates.y] != CARS)
            return result;
        return null;

//        if (result == null && temp != Integer.MAX_VALUE)
//            throw new RuntimeException("Next step not found");
    }
}


